<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html class="js" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" version="XHTML+RDFa 1.0" dir="ltr" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/terms/" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:og="http://ogp.me/ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:sioc="http://rdfs.org/sioc/ns#" xmlns:sioct="http://rdfs.org/sioc/types#" xmlns:skos="http://www.w3.org/2004/02/skos/core#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#"><head profile="http://www.w3.org/1999/xhtml/vocab">
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="shortcut icon" href="http://www.catch22.net/sites/all/themes/catch22/favicon.ico" type="image/vnd.microsoft.icon">
<meta content="Custom Controls" about="/tuts/custom-controls" property="dc:title">
<link rel="canonical" href="http://www.catch22.net/tuts/custom-controls">
<meta name="Generator" content="Drupal 7 (http://drupal.org)">
<link rel="shortlink" href="http://www.catch22.net/node/408">
  <title>Custom Controls | Catch22</title>
  <link type="text/css" rel="stylesheet" href="Custom%20Controls%20_%20Catch22_files/css_pbm0lsQQJ7A7WCCIMgxLho6mI_kBNgznNUWmTWcnfoE.css" media="all">
<link type="text/css" rel="stylesheet" href="Custom%20Controls%20_%20Catch22_files/css_xLKejvFHysXp-l3laViVkLJ1ayzcTAFQJbq6WjkyPLA.css" media="all">
<link type="text/css" rel="stylesheet" href="Custom%20Controls%20_%20Catch22_files/css_ZQkkisGoPl_8KVdJmwuISnUI43N7d4JYzaGdvEjF92I.css" media="all">
<link type="text/css" rel="stylesheet" href="Custom%20Controls%20_%20Catch22_files/css_47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU.css" media="all">
<link type="text/css" rel="stylesheet" href="Custom%20Controls%20_%20Catch22_files/catch22.css" media="all">
<link type="text/css" rel="stylesheet" href="Custom%20Controls%20_%20Catch22_files/css_47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU.css" media="all">
<link type="text/css" rel="stylesheet" href="Custom%20Controls%20_%20Catch22_files/css_47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU.css" media="print">
  <script type="text/javascript" src="Custom%20Controls%20_%20Catch22_files/js_3jHghlMLrjr9xXAC0JufqSSch3oAbkZstSqYdc4uuck.js"></script>
<script type="text/javascript" src="Custom%20Controls%20_%20Catch22_files/js_Nd1owDSs38ho6pJ1jmWFExNc9Dl4fdwRcNpkod5Riqo.js"></script>
<script type="text/javascript" src="Custom%20Controls%20_%20Catch22_files/js_RX1aIFdCtJNi_n9B6eZ_YCBRbvbvcMeF7gZ_bx0R5ps.js"></script>
<script type="text/javascript" src="Custom%20Controls%20_%20Catch22_files/lightbox.js"></script>
<script type="text/javascript" src="Custom%20Controls%20_%20Catch22_files/js_dTzpEfg5C8aCKXF1xNgEebophY6fm3bvn1HT7ZtCxpM.js"></script>
<script type="text/javascript">
<!--//--><![CDATA[//><!--
jQuery.extend(Drupal.settings, {"basePath":"\u002F", "pathPrefix":"", "ajaxPageState":{"theme":"catch22", "theme_token":"IoYRk12jHoN1hKwdoaIlXTrKrFVs7TgmkNo52l3lw_A", "js":{"sites\u002Fall\u002Fmodules\u002Fsyntaxhighlighter\u002Fsyntaxhighlighter.min.js":1, "misc\u002Fjquery.js":1, "misc\u002Fjquery.once.js":1, "misc\u002Fdrupal.js":1, "sites\u002Fall\u002Flibraries\u002Fsyntaxhighlighter_3.0.83\u002Fscripts\u002FshCore.js":1, "sites\u002Fall\u002Flibraries\u002Fsyntaxhighlighter_3.0.83\u002Fscripts\u002FshBrushCpp.js":1, "sites\u002Fall\u002Flibraries\u002Fsyntaxhighlighter_3.0.83\u002Fscripts\u002FshBrushPhp.js":1, "sites\u002Fall\u002Fmodules\u002Fgeo_filter\u002Fgeo_filter.js":1, "sites\u002Fall\u002Fmodules\u002Flightbox2\u002Fjs\u002Flightbox.js":1, "sites\u002Fall\u002Fmodules\u002Fpanels\u002Fjs\u002Fpanels.js":1}, "css":{"modules\u002Fsystem\u002Fsystem.base.css":1, "modules\u002Fsystem\u002Fsystem.menus.css":1, "modules\u002Fsystem\u002Fsystem.messages.css":1, "modules\u002Fsystem\u002Fsystem.theme.css":1, "modules\u002Fbook\u002Fbook.css":1, "modules\u002Ffield\u002Ftheme\u002Ffield.css":1, "modules\u002Fnode\u002Fnode.css":1, "modules\u002Fsearch\u002Fsearch.css":1, "modules\u002Fuser\u002Fuser.css":1, "sites\u002Fall\u002Fmodules\u002Fviews\u002Fcss\u002Fviews.css":1, "sites\u002Fall\u002Fmodules\u002Fckeditor\u002Fckeditor.css":1, "sites\u002Fall\u002Fmodules\u002Fctools\u002Fcss\u002Fctools.css":1, "sites\u002Fall\u002Fmodules\u002Flightbox2\u002Fcss\u002Flightbox.css":1, "sites\u002Fall\u002Fmodules\u002Fpanels\u002Fcss\u002Fpanels.css":1, "sites\u002Fall\u002Flibraries\u002Fsyntaxhighlighter_3.0.83\u002Fstyles\u002FshCore.css":1, "sites\u002Fall\u002Flibraries\u002Fsyntaxhighlighter_3.0.83\u002Fstyles\u002FshThemeRDark.css":1, "sites\u002Fall\u002Fthemes\u002Fcatch22\u002Fcss\u002Fdefault.css":1, "sites\u002Fall\u002Fthemes\u002Fcatch22\u002Fcss\u002Fcatch22.scss":1, "sites\u002Fall\u002Fthemes\u002Fcatch22\u002Fcss\u002Flayout.css":1, "sites\u002Fall\u002Fthemes\u002Fcatch22\u002Fcss\u002Fstyle.css":1, "sites\u002Fall\u002Fthemes\u002Fcatch22\u002Fcss\u002Fprint.css":1}}, "lightbox2":{"rtl":0, "file_path":"\u002F(\u005Cw\u005Cw\u002F)public:\u002F", "default_image":"\u002Fsites\u002Fall\u002Fmodules\u002Flightbox2\u002Fimages\u002Fbrokenimage.jpg", "border_size":10, "font_color":"000", "box_color":"fff", "top_position":"", "overlay_opacity":"0.8", "overlay_color":"000", "disable_close_click":true, "resize_sequence":0, "resize_speed":400, "fade_in_speed":400, "slide_down_speed":600, "use_alt_layout":false, "disable_resize":false, "disable_zoom":false, "force_show_nav":false, "show_caption":true, "loop_items":false, "node_link_text":"View Image Details", "node_link_target":false, "image_count":"Image !current of !total", "video_count":"Video !current of !total", "page_count":"Page !current of !total", "lite_press_x_close":"press \u003Ca href=\u0022#\u0022 onclick=\u0022hideLightbox(); return FALSE;\u0022\u003E\u003Ckbd\u003Ex\u003C\u002Fkbd\u003E\u003C\u002Fa\u003E to close", "download_link_text":"", "enable_login":false, "enable_contact":false, "keys_close":"c x 27", "keys_previous":"p 37", "keys_next":"n 39", "keys_zoom":"z", "keys_play_pause":"32", "display_image_size":"original", "image_node_sizes":"()", "trigger_lightbox_classes":"", "trigger_lightbox_group_classes":"", "trigger_slideshow_classes":"", "trigger_lightframe_classes":"", "trigger_lightframe_group_classes":"", "custom_class_handler":0, "custom_trigger_classes":"", "disable_for_gallery_lists":true, "disable_for_acidfree_gallery_lists":true, "enable_acidfree_videos":true, "slideshow_interval":5000, "slideshow_automatic_start":true, "slideshow_automatic_exit":true, "show_play_pause":true, "pause_on_next_click":false, "pause_on_previous_click":true, "loop_slides":false, "iframe_width":600, "iframe_height":400, "iframe_border":1, "enable_video":false}});
//--><!]]>
</script>
</head>
<body style="cursor: default;" class="html not-front not-logged-in two-sidebars page-node page-node- page-node-408 node-type-tutorial lightbox-processed">
  <div id="skip-link">
    <a href="#main-content" class="element-invisible element-focusable">Skip to main content</a>
  </div>
    <div id="page" class="page">

  <!-- ______________________ HEADER _______________________ -->

  <div id="header">
    <div id="header-inner">
    

          <div id="name-and-slogan">
                  <a href="http://www.catch22.net/" title="Home" rel="home" id="logo">
            <img src="Custom%20Controls%20_%20Catch22_files/logo.png" alt="Home">
          </a>
        
        
                  <div id="site-slogan">Win32 Software &amp; Programming Tutorials</div>
        
      </div>
    
    
       <div id="navigation" class="menu with-primary">
        <ul id="primary" class="links clearfix main-menu"><li class="menu-230 first"><a href="http://www.catch22.net/">Home</a></li>
<li class="menu-1311"><a href="http://www.catch22.net/software">Software</a></li>
<li class="menu-1178"><a href="http://www.catch22.net/sourcecode">Source</a></li>
<li class="menu-413 active-trail"><a href="http://www.catch22.net/tuts" class="active-trail">Tutorials</a></li>
<li class="menu-605 last"><a href="http://www.catch22.net/about">Contact</a></li>
</ul>        <!-- ?php print theme('links', array('links' => $secondary_menu, 'attributes' => array('id' => 'secondary', 'class' => array('links', 'clearfix', 'sub-menu')))); ? -->
      </div>
    
    </div> <!-- /header-inner -->
  </div> <!-- /header -->

  <!-- ______________________ MAIN _______________________ -->

  <div id="main" class="clearfix">

      <div id="sidebar-second" class="maincolumn sidebar second">
        <div id="sidebar-second-inner" class="inner">
            <div class="region region-sidebar-second">
    <div id="block-attachments-attachments" class="block block-attachments block-first block-last">

    
  <div class="content">
    <div class="file-attachment first"><img class="fileicon" src="Custom%20Controls%20_%20Catch22_files/application-zip.png"><a href="http://www.catch22.net/sites/default/files/custctrl.zip">custctrl.zip</a><div class="clearfix"></div><p>Published on <b>22 Jan 2012</b></p><p><b>7.37 Kb</b></p><a class="button" href="http://www.catch22.net/sites/default/files/custctrl.zip">Download</a><div class="clearfix"></div></div>  </div>
</div>
  </div>
        </div>
      </div>
     <!-- /sidebar-second -->

  

    <div id="content" class="maincolumn">
      <div id="content-inner" class="inner column center">

                  <div id="content-header">

            <!-- ?php print $breadcrumb; ? -->

            
                          <div class="tabs"></div>
            
                          <h1 class="title">Custom Controls</h1>
            
                        


                        
          </div> <!-- /#content-header -->
        
        <div id="content-area">
            <div class="region region-content">
    <div id="block-system-main" class="block block-system block-first block-last">

    
  <div class="content">
    <div id="node-408" class="node node-tutorial node-promoted">
	<div class="node-inner">
    
    
    <h2 class="subtitle">How to create a custom win32 control</h2>

    <!-- ?php print $user_picture; ? -->
		    
    <!-- ?php if ($display_submitted): ? -->
      <!-- span class="submitted" -->
  

  	<div class="content">
  	  <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even" property="content:encoded"><p>A
 custom control is any child window which displays information or allows
 the user to interact with it in some way. This article describes the 
steps required to create a custom user control from scratch, using pure 
Win32 techniques. This custom control will not be an ActiveX control, or
 possess any other magical properties. Rather, we will be creating a 
simple control, similar to the way edit controls, buttons or listboxes 
work.</p>
<p>The example control we will build will be a simple text label, but 
will change colour whenever the user clicks on it. This simple example 
will be sufficient to help explain all the steps necessary to create any
 custom control.</p>
<p><img alt="Custom Control demo" src="Custom%20Controls%20_%20Catch22_files/custctrl03.gif" height="132" width="285" border="0"></p>
<h2>
	Getting Started</h2>
<p>A custom control is nothing special. It is just a standard window, 
but created with the WS_CHILD style set. The custom part comes in 
because we write a new window procedure to provide the necessary control
 display and interaction.</p>
<p>So, first things first. We're going to create a new source-file to 
put just the custom-control code in. Call this CustCtrl.c or something. 
If you take this modular approach from the start you will find it so 
much easier to develop and maintain your code. This source file just 
needs to contain the following two lines for now:</p>
<div><div id="highlighter_190696" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp preprocessor">#include &lt;windows.h&gt;</code></div><div class="line number2 index1 alt1"><code class="cpp preprocessor">#include &lt;tchar.h&gt;</code></div></div></td></tr></tbody></table></div></div><p>The
 &lt;tchar.h&gt; file enables us to write Unicode-compatible windows 
programs. In a few places in the code, you will see things like "TCHAR" 
and "_T". These are macros defined in &lt;tchar.h&gt;, which help us to 
easily create Unicode applications, if we want. Our custom control won't
 be Unicode, but it could be if we used the correct compiler settings.</p>
<p>In order to create a new type of window, we need to register a new 
window class. This is achieved with the RegisterClassEx API call, shown 
below.</p>
<div><div id="highlighter_580775" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">TCHAR</code> <code class="cpp plain">szClassName[] = _T(</code><code class="cpp string">"CustCtrl345"</code><code class="cpp plain">);</code></div><div class="line number2 index1 alt1">&nbsp;</div><div class="line number3 index2 alt2"><code class="cpp keyword bold">void</code> <code class="cpp plain">InitCustomControl()</code></div><div class="line number4 index3 alt1"><code class="cpp plain">{</code></div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">WNDCLASSEX wc;</code></div><div class="line number6 index5 alt1">&nbsp;</div><div class="line number7 index6 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">wc.cbSize&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = </code><code class="cpp keyword bold">sizeof</code><code class="cpp plain">(wc);</code></div><div class="line number8 index7 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">wc.lpszClassName&nbsp; = szClassName;</code></div><div class="line number9 index8 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">wc.hInstance&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = GetModuleHandle(0);</code></div><div class="line number10 index9 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">wc.lpfnWndProc&nbsp;&nbsp;&nbsp; = CustWndProc;</code></div><div class="line number11 index10 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">wc.hCursor&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = LoadCursor (NULL, IDC_ARROW);</code></div><div class="line number12 index11 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">wc.hIcon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 0;</code></div><div class="line number13 index12 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">wc.lpszMenuName&nbsp;&nbsp; = 0;</code></div><div class="line number14 index13 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">wc.hbrBackground&nbsp; = (</code><code class="cpp color1 bold">HBRUSH</code><code class="cpp plain">)GetSysColorBrush(COLOR_BTNFACE);</code></div><div class="line number15 index14 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">wc.style&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 0;</code></div><div class="line number16 index15 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">wc.cbClsExtra&nbsp;&nbsp;&nbsp;&nbsp; = 0;</code></div><div class="line number17 index16 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">wc.cbWndExtra&nbsp;&nbsp;&nbsp;&nbsp; = 0;</code></div><div class="line number18 index17 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">wc.hIconSm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 0;</code></div><div class="line number19 index18 alt2">&nbsp;</div><div class="line number20 index19 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">RegisterClassEx(&amp;wc);</code></div><div class="line number21 index20 alt2"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div><p>So far so good. The next step is to write a window procedure (<b>CustWndProc</b>) which the custom control uses to process it's messages. This is just a standard window procedure, like the one shown below.</p>
<div><div id="highlighter_122377" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">LRESULT</code> <code class="cpp plain">CALLBACK CustWndProc(</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwnd, </code><code class="cpp color1 bold">UINT</code> <code class="cpp plain">msg, </code><code class="cpp color1 bold">WPARAM</code> <code class="cpp plain">wParam, </code><code class="cpp color1 bold">LPARAM</code> <code class="cpp plain">lParam)</code></div><div class="line number2 index1 alt1"><code class="cpp plain">{</code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">switch</code><code class="cpp plain">(msg)</code></div><div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">{</code></div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">default</code><code class="cpp plain">:</code></div><div class="line number6 index5 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">break</code><code class="cpp plain">;</code></div><div class="line number7 index6 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">}</code></div><div class="line number8 index7 alt1">&nbsp;</div><div class="line number9 index8 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">DefWindowProc(hwnd, msg, wParam, lParam);</code></div><div class="line number10 index9 alt1"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div><p>Now,
 it may look as if this window procedure doesn't actually do anything, 
but this is not the case. The DefWindowProc API call performs alot of 
default processing (window focus, painting, activation etc) for a 
window. It is only when we need to provide additional functionality 
(like drawing the window focus) that we need to start filling in that <b>switch</b> statement to handle specific windows messages.</p>
<h2>
	Creating the control</h2>
<p>Now we can create a custom control! There are two ways to do this. 
The first is to manually create the control at run-time (probably in the
 main window's WM_CREATE message, or something similar). This is 
achieved with the <b>CreateWindowEx</b> API call, like this:</p>
<div><div id="highlighter_860457" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">HWND</code> <code class="cpp plain">CreateCustomControl(</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwndParent)</code></div><div class="line number2 index1 alt1"><code class="cpp plain">{</code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwndCtrl;</code></div><div class="line number4 index3 alt1">&nbsp;</div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">hwndCtrl = CreateWindowEx(</code></div><div class="line number6 index5 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">WS_EX_CLIENTEDGE, </code><code class="cpp comments">// give it a standard border</code></div><div class="line number7 index6 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">szClassName,</code></div><div class="line number8 index7 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">_T(</code><code class="cpp string">"A custom control"</code><code class="cpp plain">),</code></div><div class="line number9 index8 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">WS_VISIBLE | WS_CHILD,</code></div><div class="line number10 index9 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">0, 0, 100, 100,</code></div><div class="line number11 index10 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">hwndParent,</code></div><div class="line number12 index11 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">NULL, GetModuleHandle(0), NULL</code></div><div class="line number13 index12 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">);</code></div><div class="line number14 index13 alt1">&nbsp;</div><div class="line number15 index14 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">hwndCtrl;</code></div><div class="line number16 index15 alt1"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div><p>The
 second way, assuming you are using some kind of resource editor (like 
in Visual C++), is to create a custom control in a dialog template, in 
the exact same way you might place edit controls or list boxes on a 
dialog box. The only difference is, you create a "Custom Control", and 
manually define the name of the window class (in this case, 
"CustCtrl345"). When your dialog is created, Windows automatically 
creates the custom control for you, and gives it a control ID.</p>
<p><img alt="Creating a custom control with visual studio" src="Custom%20Controls%20_%20Catch22_files/custctrl02.gif" height="406" width="403" border="0"></p>
<h2>
	Custom control state information</h2>
<p>At some point in time, you will want to make the control do 
something. And, unless your control is going to be extremely simple, you
 will undoubtably want to define variables, text strings or arrays to 
represent the state of the control. For example, in a custom list 
control, you would at the very least need to keep track of the items in 
the list, using an array or linked list. You would also need a variable 
which keeps track of how many items there are in your list. In addition,
 if you want your control to be scrollable, you will need to keep track 
of the scrollbar position, and the minimum and maximum scroll ranges.</p>
<p>You need to take my word that you will need to define a structure (or
 class, if you are using C++) which will encapsulate ALL of the 
control's state information. If you take this approach (and avoid using 
global variables), you will be able to create multiple custom controls 
at the same time, and each one will look after itself.</p>
<p>We need to decide what attributes our custom control will have. The list below describes these attributes.</p>
<ul><li>
		Text colour (Foreground and Background)</li>
<li>
		Display text (what the control actually displays)</li>
<li>
		Font (what type-face the text will be drawn in)</li>
</ul><p>The following structure will hold some simple state information.</p>
<div><div id="highlighter_148477" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp keyword bold">typedef</code> <code class="cpp keyword bold">struct</code></div><div class="line number2 index1 alt1"><code class="cpp plain">{</code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">COLORREF</code> <code class="cpp plain">crForeGnd;&nbsp;&nbsp;&nbsp; </code><code class="cpp comments">// Foreground text colour</code></div><div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">COLORREF</code> <code class="cpp plain">crBackGnd;&nbsp;&nbsp;&nbsp; </code><code class="cpp comments">// Background text colour</code></div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">HFONT</code>&nbsp;&nbsp;&nbsp; <code class="cpp plain">hFont;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code><code class="cpp comments">// The font</code></div><div class="line number6 index5 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">HWND</code>&nbsp;&nbsp;&nbsp;&nbsp; <code class="cpp plain">hwnd;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code><code class="cpp comments">// The control's window handle</code></div><div class="line number7 index6 alt2"><code class="cpp plain">} CustCtrl;</code></div></div></td></tr></tbody></table></div></div><p>The
 one element missing from this structure is the display text. For our 
simple example, this is not necessary, because every window has it's own
 window text. Therefore we will just use this standard window text when 
we draw the control. For more complicated controls (lists, edit 
controls), you would need to store the text yourself.</p>
<h2>
	Associating a structure with the custom control</h2>
<p>At this point you will hit a stumbling block. The problem is, your 
custom window procedure is a simple callback function, which processes 
all messages for all custom controls you create. Depending on which 
window is currently having it's message processed, we will have to 
obtain the correct state structure for that window, and use that 
structure when processing the message.</p>
<p>There are many ways to "attach" a structure to a window. Which one 
you use can depend on many things, but I will describe each method 
below. First though, we will define two simple functions, which will set
 and retrieve our custom structure for a window:</p>
<div><div id="highlighter_383167" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp plain">CustCtrl * GetCustCtrl(</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwnd)</code></div><div class="line number2 index1 alt1"><code class="cpp plain">{</code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// get pointer to structure, then return it</code></div><div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">CustCtrl *ccp = ???</code></div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">ccp;</code></div><div class="line number6 index5 alt1"><code class="cpp plain">}</code></div><div class="line number7 index6 alt2">&nbsp;</div><div class="line number8 index7 alt1"><code class="cpp keyword bold">void</code> <code class="cpp plain">SetCustCtrl(</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwnd, CustCtrl *ccp)</code></div><div class="line number9 index8 alt2"><code class="cpp plain">{</code></div><div class="line number10 index9 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// attach pointer to window</code></div><div class="line number11 index10 alt2"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div><h3>
	The GWL_USERDATA area.</h3>
<p>Every window in the system has a 32bit integer which can be set to 
any value. This 4 byte storage area is enough to store a pointer to a 
structure. We set this integer using SetWindowLong, and retrieve the 
integer using GetWindowLong. Using this technique, our function will 
look like this:</p>
<div><div id="highlighter_825858" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp plain">CustCtrl * GetCustCtrl(</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwnd)</code></div><div class="line number2 index1 alt1"><code class="cpp plain">{</code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">(CustCtrl *)GetWindowLong(hwnd, GWL_USERDATA);</code></div><div class="line number4 index3 alt1"><code class="cpp plain">}</code></div><div class="line number5 index4 alt2">&nbsp;</div><div class="line number6 index5 alt1"><code class="cpp keyword bold">void</code> <code class="cpp plain">SetCustCtrl(</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwnd, CustCtrl *ccp)</code></div><div class="line number7 index6 alt2"><code class="cpp plain">{</code></div><div class="line number8 index7 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">SetWindowLong(hwnd, GWL_USERDATA, (</code><code class="cpp color1 bold">LONG</code><code class="cpp plain">)ccp);</code></div><div class="line number9 index8 alt2"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div><p>This
 method is usually used when subclassing a control rather than writing 
one from scratch, because there are better alternatives. The problem 
with this method is that any application or window can set this 
user-data-area, so you need to be careful it is never used by two 
conflicting components.</p>
<h3>
	Window Properties</h3>
<p>Window properties allow a program to attach multiple 32bit integer 
values to a window, using a textual string as a way to map each property
 to the associated integer value. In actual fact, a window property is 
really a HANDLE value (i.e. a handle to a block of memory, or a GDI 
resource). However, a HANDLE is still a 32bit integer, so we will store a
 pointer to a custom structure as a HANDLE.</p>
<div><div id="highlighter_478543" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">TCHAR</code> <code class="cpp plain">szPropName[] = _T(</code><code class="cpp string">"CustCtrlPtr"</code><code class="cpp plain">);</code></div><div class="line number2 index1 alt1">&nbsp;</div><div class="line number3 index2 alt2"><code class="cpp plain">CustCtrl * GetCustCtrl(</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwnd)</code></div><div class="line number4 index3 alt1"><code class="cpp plain">{</code></div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">(CustCtrl *)GetProp(hwnd, szPropName);</code></div><div class="line number6 index5 alt1"><code class="cpp plain">}</code></div><div class="line number7 index6 alt2">&nbsp;</div><div class="line number8 index7 alt1"><code class="cpp keyword bold">void</code> <code class="cpp plain">SetCustCtrl(</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwnd, CustCtrl *ccp)</code></div><div class="line number9 index8 alt2"><code class="cpp plain">{</code></div><div class="line number10 index9 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">SetProp(hwnd, szPropName, (</code><code class="cpp color1 bold">HANDLE</code><code class="cpp plain">)ccp);&nbsp;&nbsp;&nbsp; </code></div><div class="line number11 index10 alt2"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div><p>This
 method will be a little slower than the rest, simply because of the 
string comparisons that windows will have to do when it retrieves a 
window property for us. It's not much slower though, and because we only
 need to do this once for every message we receive, it's not much of an 
overhead at all.</p>
<h3>
	Extra window bytes</h3>
<p>This is the best way to go if you are writing a control from scratch.
 When you initially register a control's window class, you have the 
option of specifying how many extra bytes of user-storage each window of
 that class will contain. If we set this value to be the size of a 
pointer (to our state structure), then we can use this special-purpose 
space exclusively for our custom control. This then leaves the 
GWL_USERDATA area for other purposes.</p>
<div><div id="highlighter_988911" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp comments">// Register the window class.</code></div><div class="line number2 index1 alt1"><code class="cpp plain">wc.cbWndExtra&nbsp;&nbsp;&nbsp;&nbsp; = </code><code class="cpp keyword bold">sizeof</code><code class="cpp plain">( CustCtrl * );</code></div></div></td></tr></tbody></table></div></div><div><div id="highlighter_131089" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp plain">CustCtrl * GetCustCtrl(</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwnd)</code></div><div class="line number2 index1 alt1"><code class="cpp plain">{</code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">(CustCtrl *)GetWindowLong(hwnd, 0);</code></div><div class="line number4 index3 alt1"><code class="cpp plain">}</code></div><div class="line number5 index4 alt2">&nbsp;</div><div class="line number6 index5 alt1"><code class="cpp keyword bold">void</code> <code class="cpp plain">SetCustCtrl(</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwnd, CustCtrl *ccp)</code></div><div class="line number7 index6 alt2"><code class="cpp plain">{</code></div><div class="line number8 index7 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">SetWindowLong(hwnd, 0, (</code><code class="cpp color1 bold">LONG</code><code class="cpp plain">)ccp);</code></div><div class="line number9 index8 alt2"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div><p>The
 extra window bytes are always accessed using a zero-based offset (when 
using GetWindowLong). Because we reserved space for one 32bit integer, 
this is accessed from the start of the extra bytes, therefore we use an 
index of zero.</p>
<h3>
	Indirect lookup tables</h3>
<p>The last method (which MFC uses) is to use a separate lookup table, 
which maps window handles to structures. This is basically just an array
 or hash table, with entries like this:</p>
<div><div id="highlighter_185230" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp keyword bold">typedef</code> <code class="cpp keyword bold">struct</code></div><div class="line number2 index1 alt1"><code class="cpp plain">{</code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">HWND</code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code class="cpp plain">hwnd;</code></div><div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">CustCtrl *ccp;</code></div><div class="line number5 index4 alt2"><code class="cpp plain">} WndLookup;</code></div><div class="line number6 index5 alt1">&nbsp;</div><div class="line number7 index6 alt2"><code class="cpp plain">WndLookup big_lookup[MAX_CUST_WINDOWS];</code></div></div></td></tr></tbody></table></div></div><p>Whenever
 we need to retrieve the custom structure from a window, we need to 
search the array or hash table for the correct entry. This is fairly 
quick when we only have a couple of custom windows at any time, but when
 we start to create alot of windows, this method will add quite an 
overhead. It is also difficult to intergrate this technique into a 
multi-threaded application.</p>
<h3>
	Assembly language thunks</h3>
<p>This method is included for completeness, and is quite different to 
the others described above. The technique is used by the ATL and WTL C++
 template libraries, and is a very quick method of retrieving an integer
 associated with a window. It's pretty complicated though, so our basic 
method is still preferred.</p>
<p>The basic idea is to replace the window procedure for a custom 
control with a small assembly language stub which modifies the first 
argument to the window procedure (the handle to the window), and 
replaces it with a pointer to the CustCtrl structure. The stub can look 
something like this:</p>
<div><div id="highlighter_491958" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp plain">mov&nbsp; [esp+4], CustCtrl *</code></div><div class="line number2 index1 alt1"><code class="cpp plain">jmp&nbsp; orig_proc</code></div></div></td></tr></tbody></table></div></div><p>You
 must understand the environment that this stub executes in, in order to
 understand how this trick works. When the window procedure needs to be 
called, the win32 sub-system executes a <code>CALL</code> instruction to
 pass control to the window procedure in question (which is not the 
window procedure at all, but the assembly-language stub. However, the 
very act of making a function call to a window procedure (real or not) 
results in the stack being set to the following state:</p>
<div><div id="highlighter_494872" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp plain">...&nbsp;&nbsp;&nbsp;&nbsp; ...</code></div><div class="line number2 index1 alt1"><code class="cpp plain">esp+10&nbsp; [lParam]</code></div><div class="line number3 index2 alt2"><code class="cpp plain">esp+0C&nbsp; [wParam]</code></div><div class="line number4 index3 alt1"><code class="cpp plain">esp+08&nbsp; [Message]</code></div><div class="line number5 index4 alt2"><code class="cpp plain">esp+04&nbsp; [</code><code class="cpp color1 bold">HWND</code><code class="cpp plain">]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp; [CustCtrl *]</code></div><div class="line number6 index5 alt1"><code class="cpp plain">esp+00&nbsp; [address to </code><code class="cpp keyword bold">return</code> <code class="cpp plain">to when function returns]</code></div></div></td></tr></tbody></table></div></div><p>The stub must perform two key actions when executed:</p>
<ol><li>
		Replace the <code>HWND</code> parameter on the stack with a pointer to the class or structure that we want to associate with the window.</li>
<li>
		Pass control to the real window procedure, now with it's first argument modified.</li>
</ol><p>The stub is generated at run-time, for each window and 
class/structure instance that is required. Note that the stub is 
different each time, because the structure and window procedure will be 
different. The actual op-codes for the <code>MOV</code> and <code>JMP</code> instructions must be generated for each specific case.</p>
<p>As you can imagine, this technique is very fast. The drawback though 
is that the window procedure can't make any reference to the HWND 
parameter - it has changed to be a pointer to the class / structure 
instead. This means that this structure MUST include the original HWND 
as a member, otherwise operations on the window would become impossible.</p>
<p>The window procedure, which can be a class-member-function, will look like this:</p>
<div><div id="highlighter_971648" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">UINT</code> <code class="cpp plain">WINAPI CustCtrl::WindowProc(</code><code class="cpp color1 bold">UINT</code> <code class="cpp plain">msg, </code><code class="cpp color1 bold">WPARAM</code> <code class="cpp plain">wParam, </code><code class="cpp color1 bold">LPARAM</code> <code class="cpp plain">lParam);</code></div></div></td></tr></tbody></table></div></div><p>Note that there is always a hidden first parameter to every C++ member function - the <b>*this</b> pointer. This means that the class-window procedure has full access to the whole class instance.</p>
<p>To understand more on this topic, read the following article by Fritz Onion:</p>
<p><a href="http://staff.develop.com/onion/Articles/cpprep0399.htm" target="_blank">Thunking WndProcs in ATL</a></p>
<h2>
	Creating the control, Take 2</h2>
<p>Now that we know how to attach a custom structure to a window, we can
 use this technique when we create a custom control. The actual 
CreateWindowEx call can remain the same, but our window procedure needs 
to change to incorporate the new CustCtrl structure. The differences are
 this:</p>
<ul><li>
		Allocate a new structure when the window is first created.</li>
<li>
		Initialize the structure contents to default values.</li>
<li>
		Attach the structure to the window (using a pointer to the structure).</li>
<li>
		Free the structure memory when the window is destroyed.</li>
</ul><p>The custom control's window procedure will now need to look this this:</p>
<div><div id="highlighter_577997" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">LRESULT</code> <code class="cpp plain">CALLBACK CustWndProc(</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwnd, </code><code class="cpp color1 bold">UINT</code> <code class="cpp plain">msg, </code><code class="cpp color1 bold">WPARAM</code> <code class="cpp plain">wParam, </code><code class="cpp color1 bold">LPARAM</code> <code class="cpp plain">lParam)</code></div><div class="line number2 index1 alt1"><code class="cpp plain">{</code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// retrieve the custom structure POINTER for THIS window</code></div><div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">CustCtrl *ccp = GetCustCtrl(hwnd);</code></div><div class="line number5 index4 alt2">&nbsp;</div><div class="line number6 index5 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">switch</code><code class="cpp plain">(msg)</code></div><div class="line number7 index6 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">{</code></div><div class="line number8 index7 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">case</code> <code class="cpp plain">WM_NCCREATE:</code></div><div class="line number9 index8 alt2">&nbsp;</div><div class="line number10 index9 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Allocate a new CustCtrl structure for this window.</code></div><div class="line number11 index10 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">ccp = </code><code class="cpp functions bold">malloc</code><code class="cpp plain">( </code><code class="cpp keyword bold">sizeof</code><code class="cpp plain">(CustCtrl) );</code></div><div class="line number12 index11 alt1">&nbsp;</div><div class="line number13 index12 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Failed to allocate, stop window creation.</code></div><div class="line number14 index13 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">if</code><code class="cpp plain">(ccp == NULL) </code></div><div class="line number15 index14 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">FALSE;</code></div><div class="line number16 index15 alt1">&nbsp;</div><div class="line number17 index16 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Initialize the CustCtrl structure. </code></div><div class="line number18 index17 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">ccp-&gt;hwnd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = hwnd;</code></div><div class="line number19 index18 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">ccp-&gt;crForeGnd = GetSysColor(COLOR_WINDOWTEXT);</code></div><div class="line number20 index19 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">ccp-&gt;crBackGnd = GetSysColor(COLOR_WINDOW);</code></div><div class="line number21 index20 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">ccp-&gt;hFont&nbsp;&nbsp;&nbsp;&nbsp; = GetStockObject(DEFAULT_GUI_FONT);</code></div><div class="line number22 index21 alt1">&nbsp;</div><div class="line number23 index22 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Assign the window text specified in the call to CreateWindow.</code></div><div class="line number24 index23 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">SetWindowText(hwnd, ((CREATESTRUCT *)lParam)-&gt;lpszName);</code></div><div class="line number25 index24 alt2">&nbsp;</div><div class="line number26 index25 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Attach custom structure to this window.</code></div><div class="line number27 index26 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">SetCustCtrl(hwnd, ccp);</code></div><div class="line number28 index27 alt1">&nbsp;</div><div class="line number29 index28 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Continue with window creation.</code></div><div class="line number30 index29 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">TRUE;</code></div><div class="line number31 index30 alt2">&nbsp;</div><div class="line number32 index31 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Clean up when the window is destroyed.</code></div><div class="line number33 index32 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">case</code> <code class="cpp plain">WM_NCDESTROY:</code></div><div class="line number34 index33 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp functions bold">free</code><code class="cpp plain">(ccp);</code></div><div class="line number35 index34 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">break</code><code class="cpp plain">;</code></div><div class="line number36 index35 alt1">&nbsp;</div><div class="line number37 index36 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">default</code><code class="cpp plain">:</code></div><div class="line number38 index37 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">break</code><code class="cpp plain">;</code></div><div class="line number39 index38 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">}</code></div><div class="line number40 index39 alt1">&nbsp;</div><div class="line number41 index40 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">DefWindowProc(hwnd, msg, wParam, lParam);</code></div><div class="line number42 index41 alt1"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div><p>Note the use of the <b>WM_NCCREATE</b> and <b>WM_NCDESTROY</b>
 messages here. These are the first and last messages to be received by a
 window, respectively. By using these messages to allocate and free our 
custom structure, we can be sure that this structure will be in 
existance for all other window messages we receive.</p>
<h2>
	Adding control functionality</h2>
<p>At this point we can create as many custom controls as we desire. The
 windows won't actually display or do anything, but you can manipulate 
them, size them etc, just like any other window you create. Let's start 
to add the control's functionality though.</p>
<p>The first step is to start writing message handler functions for 
every message you want to handle. It is a very good idea to write a 
separate function for each message. This keeps the window procedure neat
 and simple, and keeps your code nice and modular. I can't stress this 
point enough - get into the habit of writing separate functions right 
from the start, because it makes writing your code so much simpler in 
the long run.</p>
<h3>
	Painting the control</h3>
<p>Whenever windows wants us to update the contents of our window (the client area), a <b>WM_PAINT</b> message will be sent. So, whenever the WM_PAINT message is received, we need to call our control's painting routine.</p>
<div><div id="highlighter_818953" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp keyword bold">case</code> <code class="cpp plain">WM_PAINT:</code></div><div class="line number2 index1 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">CustCtrl_OnPaint(ccp, wParam, lParam);</code></div></div></td></tr></tbody></table></div></div><p>Note
 how the pointer to the control structure is passed to the message 
handler function. This will be the same for any message we handle. Now, 
the actual paint handler will look something like this:</p>
<div><div id="highlighter_157732" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">LRESULT</code> <code class="cpp plain">CustCtrl_OnPaint(CustCtrl *ccp, </code><code class="cpp color1 bold">WPARAM</code> <code class="cpp plain">wParam, </code><code class="cpp color1 bold">LPARAM</code> <code class="cpp plain">lParam)</code></div><div class="line number2 index1 alt1"><code class="cpp plain">{</code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">HDC</code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code class="cpp plain">hdc;</code></div><div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">PAINTSTRUCT&nbsp; ps;</code></div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">HANDLE</code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code class="cpp plain">hOldFont;</code></div><div class="line number6 index5 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">TCHAR</code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code class="cpp plain">szText[200];</code></div><div class="line number7 index6 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">RECT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rect;</code></div><div class="line number8 index7 alt1">&nbsp;</div><div class="line number9 index8 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Get a device context for this window</code></div><div class="line number10 index9 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">hdc = BeginPaint(ccp-&gt;hwnd, &amp;ps);</code></div><div class="line number11 index10 alt2">&nbsp;</div><div class="line number12 index11 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Set the font we are going to use</code></div><div class="line number13 index12 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">hOldFont = SelectObject(hdc, ccp-&gt;hFont);</code></div><div class="line number14 index13 alt1">&nbsp;</div><div class="line number15 index14 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Set the text colours</code></div><div class="line number16 index15 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">SetTextColor(hdc, ccp-&gt;crForeGnd);</code></div><div class="line number17 index16 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">SetBkColor&nbsp; (hdc, ccp-&gt;crBackGnd);</code></div><div class="line number18 index17 alt1">&nbsp;</div><div class="line number19 index18 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Find the text to draw</code></div><div class="line number20 index19 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">GetWindowText(ccp-&gt;hwnd, szText, </code><code class="cpp keyword bold">sizeof</code><code class="cpp plain">(szText));</code></div><div class="line number21 index20 alt2">&nbsp;</div><div class="line number22 index21 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Work out where to draw</code></div><div class="line number23 index22 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">GetClientRect(ccp-&gt;hwnd, &amp;rect);</code></div><div class="line number24 index23 alt1">&nbsp;</div><div class="line number25 index24 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Find out how big the text will be</code></div><div class="line number26 index25 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">GetTextExtentPoint32(hdc, szText, lstrlen(szText), &amp;sz);</code></div><div class="line number27 index26 alt2">&nbsp;</div><div class="line number28 index27 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Center the text</code></div><div class="line number29 index28 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">x = (rect.right&nbsp; - sz.cx) / 2;</code></div><div class="line number30 index29 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">y = (rect.bottom - sz.cy) / 2;</code></div><div class="line number31 index30 alt2">&nbsp;</div><div class="line number32 index31 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Draw the text</code></div><div class="line number33 index32 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">ExtTextOut(hdc, x, y, ETO_OPAQUE, &amp;rect, szText, lstrlen(szText), 0);</code></div><div class="line number34 index33 alt1">&nbsp;</div><div class="line number35 index34 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Restore the old font when we have finished</code></div><div class="line number36 index35 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">SelectObject(hdc, hOldFont);</code></div><div class="line number37 index36 alt2">&nbsp;</div><div class="line number38 index37 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Release the device context</code></div><div class="line number39 index38 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">EndPaint(ccp-&gt;hwnd, &amp;ps);</code></div><div class="line number40 index39 alt1">&nbsp;</div><div class="line number41 index40 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">0;</code></div><div class="line number42 index41 alt1"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div><h3>
	Undocumented painting tips</h3>
<p>I just want to mention an important feature of Windows here. The standard documention states that <b>wParam</b> and <b>lParam</b> will both be zero for the <b>WM_PAINT</b> message. This is fine, because we can do everything we want with the <b>BeginPaint</b> / <b>EndPaint</b> technique.</p>
<p><b>However</b>, for alot of standard controls, Windows will sometimes send a <b>WM_PAINT</b>
 message with wParam set to a handle to a device context. In other 
words, Windows sometimes supplies a device-context for you, which will 
result in faster drawing. This means that it is not strictly necessary 
to use the BeginPaint/EndPaint pair all of the time. To take advantage 
of this scenario, you could check wParam to see if it is zero or not. If
 it isn't, then instead of using BeginPaint to get a device context, 
just use wParam as your HDC. i.e.</p>
<div><div id="highlighter_911664" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp keyword bold">if</code><code class="cpp plain">(wParam == 0)</code></div><div class="line number2 index1 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">hdc = BeginPaint(ccp-&gt;hwnd, &amp;ps);</code></div><div class="line number3 index2 alt2"><code class="cpp keyword bold">else</code></div><div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">hdc = (</code><code class="cpp color1 bold">HDC</code><code class="cpp plain">)wParam;</code></div></div></td></tr></tbody></table></div></div><p>Don't forget to do the same test when you come to call <b>EndPaint</b> - in fact, don't do anything when you have a pre-supplied HDC from Windows.</p>
<p>Now, you need to be careful using this technique, because the device 
context that windows supplies will not be initialized to it's default 
state, so you need to make sure that you set the device context up in 
the correct mapping mode, set the correct colours etc. (i.e, don't 
assume that the device context will be in a certain state). Also, you 
must restore ANY setting that you modify, be it font, mapping modes, 
colours etc.</p>
<p>The custom control presented here does not use this alternative 
painting method, so you can safely ignore this information if you want.</p>
<h3>
	Preventing flicker</h3>
<p>Currently, the control will flicker slightly each time it is painted. This is because it is getting painted twice for every <b>WM_PAINT</b> it receives. The problem is the <b>WM_ERASEBKGND</b> message, which is sent every time we call <b>BeginPaint</b>.
 This isn't a problem really - Windows is doing us a favour, because the
 default action for WM_ERASEBKGND is to draw a nice window background 
for us (using the window's default background brush), which we can then 
paint on top of in the WM_PAINT handler.</p>
<p>However, our WM_PAINT handler also draws the control's background, so
 there is no point in this happening twice. Therefore, we need to 
prevent the default WM_ERASEBKGND behaviour from happending. As usual, 
there are a number of ways to do this.</p>
<ul><li>
		Set the window's background brush to NULL. (Set the <b>hbrBackground</b> member of the <b>WNDCLASS</b> structure to zero when you register the window class).</li>
<li>
		Return non-zero in the WM_ERASEBKGND message handler.</li>
</ul><p>Any one of these will steps will prevent the WM_ERASEBKGND 
message from clearing the window. We will therefore choose the last 
option, because it is the simplest to implement:</p>
<div><div id="highlighter_962758" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp keyword bold">case</code> <code class="cpp plain">WM_ERASEBKGND:</code></div><div class="line number2 index1 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">1;</code></div></div></td></tr></tbody></table></div></div><h3>
	Responding to user interaction</h3>
<p>Our custom control will change colour whenever the user clicks the 
mouse on it. Therefore the next message handler will be for the <b>WM_LBUTTONDOWN</b> message.</p>
<div><div id="highlighter_551915" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp keyword bold">case</code> <code class="cpp plain">WM_LBUTTONDOWN:</code></div><div class="line number2 index1 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">CustCtrl_OnLButtonDown(ccp, wParam, lParam);</code></div></div></td></tr></tbody></table></div></div><div><div id="highlighter_576822" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">LRESULT</code> <code class="cpp plain">CustCtrl_OnLButtonDown(CustCtrl *ccp, </code><code class="cpp color1 bold">WPARAM</code> <code class="cpp plain">wParam, </code><code class="cpp color1 bold">LPARAM</code> <code class="cpp plain">lParam)</code></div><div class="line number2 index1 alt1"><code class="cpp plain">{</code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">COLORREF</code> <code class="cpp plain">col = RGB( </code><code class="cpp functions bold">rand</code><code class="cpp plain">()%256, </code><code class="cpp functions bold">rand</code><code class="cpp plain">()%256, </code><code class="cpp functions bold">rand</code><code class="cpp plain">()%256 );</code></div><div class="line number4 index3 alt1">&nbsp;</div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Change the foreground colour</code></div><div class="line number6 index5 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">ccp-&gt;crForeGnd = col;</code></div><div class="line number7 index6 alt2">&nbsp;</div><div class="line number8 index7 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Use the inverse of the foreground colour</code></div><div class="line number9 index8 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">ccp-&gt;crBackGnd = ((~col) &amp; 0x00ffffff);</code></div><div class="line number10 index9 alt1">&nbsp;</div><div class="line number11 index10 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Now redraw the control</code></div><div class="line number12 index11 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">InvalidateRect(ccp-&gt;hwnd, NULL, FALSE);</code></div><div class="line number13 index12 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">UpdateWindow(ccp-&gt;hwnd);</code></div><div class="line number14 index13 alt1">&nbsp;</div><div class="line number15 index14 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">0;</code></div><div class="line number16 index15 alt1"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div><h3>
	Receiving input focus</h3>
<p>When a user clicks on a window or control it does <em>not</em> 
automatically receive the keyboard-input focus. Think about it for a 
while: controls like toolbars and static controls never cause the 
input-focus to change when you click on them so there must be something 
else we need to do when the mouse is clicked in our window.</p>
<p>Rather than using the WM_LBUTTONDOWN message (which can be received 
many times by a window) we will uFor our control to receive input focus 
we must react to the WM_MOUSEACTIVATE message:</p>
<div><div id="highlighter_561909" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp keyword bold">case</code> <code class="cpp plain">WM_MOUSEACTIVATE:</code></div><div class="line number2 index1 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">SetFocus(hwnd);</code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">MA_ACTIVATE;</code></div></div></td></tr></tbody></table></div></div><p>By manually setting the input-focus to our control we</p>
<h3>
	Font support</h3>
<p>Currently, our custom control only supports the default system font, 
so we will handle the WM_SETFONT message. Handling this message will 
allow us to change the font whenever requested by windows.</p>
<div><div id="highlighter_960158" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp keyword bold">case</code> <code class="cpp plain">WM_SETFONT:</code></div><div class="line number2 index1 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">CustCtrl_OnSetFont(ccp, wParam, lParam);</code></div></div></td></tr></tbody></table></div></div><div><div id="highlighter_868495" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">LRESULT</code> <code class="cpp plain">CustCtrl_OnSetFont(CustCtrl *ccp, </code><code class="cpp color1 bold">WPARAM</code> <code class="cpp plain">wParam, </code><code class="cpp color1 bold">LPARAM</code> <code class="cpp plain">lParam)</code></div><div class="line number2 index1 alt1"><code class="cpp plain">{</code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Change the font</code></div><div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">ccp-&gt;hFont = (</code><code class="cpp color1 bold">HFONT</code><code class="cpp plain">)wParam; </code></div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">0;</code></div><div class="line number6 index5 alt1"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div><h2>
	Mission Completed</h2>
<p>At this point in time we need go no further. What you have is a 
complete custom control. It is now up to you to experiment with the 
control, to add further features, or to start again using the steps 
described to create your very own control.</p>
<p>There are still a few things I want to say about writing custom controls, so read on if you havn't fallen asleep yet!</p>
<h2>
	Using message cracker macros</h2>
<p>Message Crackers are pre-processor macros, define in WINDOWSX.H (available with the Platform SDK).</p>
<h2>
	If you are using C++</h2>
<p>It is quite possible to use C++ to write your custom control. In 
fact, it is alot easier than using plain C, because you can create a 
miniture object framework which makes writing the window procedure a 
dream. Instead of using a structure to define the control state, you can
 use a class. And the message handler functions can become member 
functions of that class.</p>
<p>As a quick example, let's redefine the structure we used for the custom control:</p>
<div><div id="highlighter_301342" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp keyword bold">class</code> <code class="cpp plain">CustCtrl</code></div><div class="line number2 index1 alt1">&nbsp;</div><div class="line number3 index2 alt2"><code class="cpp plain">{</code></div><div class="line number4 index3 alt1"><code class="cpp keyword bold">public</code><code class="cpp plain">:</code></div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">CustCtrl(</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">h);</code></div><div class="line number6 index5 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">~CustCtrl();</code></div><div class="line number7 index6 alt2">&nbsp;</div><div class="line number8 index7 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// message handlers</code></div><div class="line number9 index8 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">LRESULT</code> <code class="cpp plain">OnPaint&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (</code><code class="cpp color1 bold">WPARAM</code> <code class="cpp plain">wParam, </code><code class="cpp color1 bold">LPARAM</code> <code class="cpp plain">lParam);</code></div><div class="line number10 index9 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">LRESULT</code> <code class="cpp plain">OnLButtonDown (</code><code class="cpp color1 bold">WPARAM</code> <code class="cpp plain">wParam, </code><code class="cpp color1 bold">LPARAM</code> <code class="cpp plain">lParam);</code></div><div class="line number11 index10 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">LRESULT</code> <code class="cpp plain">OnSetFont&nbsp;&nbsp;&nbsp;&nbsp; (</code><code class="cpp color1 bold">WPARAM</code> <code class="cpp plain">wParam, </code><code class="cpp color1 bold">LPARAM</code> <code class="cpp plain">lParam);</code></div><div class="line number12 index11 alt1">&nbsp;</div><div class="line number13 index12 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// window procedure</code></div><div class="line number14 index13 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">static</code> <code class="cpp color1 bold">LRESULT</code> <code class="cpp plain">CALLBACK WndProc(</code></div><div class="line number15 index14 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwnd, </code><code class="cpp color1 bold">UINT</code> <code class="cpp plain">msg, </code><code class="cpp color1 bold">WPARAM</code> <code class="cpp plain">wParam, </code><code class="cpp color1 bold">LPARAM</code> <code class="cpp plain">lParam</code></div><div class="line number16 index15 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">);</code></div><div class="line number17 index16 alt2">&nbsp;</div><div class="line number18 index17 alt1"><code class="cpp keyword bold">private</code><code class="cpp plain">:</code></div><div class="line number19 index18 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">COLORREF</code> <code class="cpp plain">crForeGnd;&nbsp;&nbsp;&nbsp; </code><code class="cpp comments">// Foreground text colour</code></div><div class="line number20 index19 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">COLORREF</code> <code class="cpp plain">crBackGnd;&nbsp;&nbsp;&nbsp; </code><code class="cpp comments">// Background text colour</code></div><div class="line number21 index20 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">HFONT</code>&nbsp;&nbsp;&nbsp; <code class="cpp plain">hFont;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code><code class="cpp comments">// The font</code></div><div class="line number22 index21 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">HWND</code>&nbsp;&nbsp;&nbsp;&nbsp; <code class="cpp plain">hwnd;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code><code class="cpp comments">// The control's window handle</code></div><div class="line number23 index22 alt2"><code class="cpp plain">};</code></div></div></td></tr></tbody></table></div></div><p>The window procedure now looks like this:</p>
<div><div id="highlighter_17071" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">LRESULT</code> <code class="cpp plain">CALLBACK CustCtrl::WndProc(</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwnd, </code><code class="cpp color1 bold">UINT</code> <code class="cpp plain">msg, </code><code class="cpp color1 bold">WPARAM</code> <code class="cpp plain">wParam, </code><code class="cpp color1 bold">LPARAM</code> <code class="cpp plain">lParam)</code></div><div class="line number2 index1 alt1"><code class="cpp plain">{</code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// retrieve the custom structure POINTER for THIS window</code></div><div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">CustCtrl *ccp = GetCustCtrl(hwnd);</code></div><div class="line number5 index4 alt2">&nbsp;</div><div class="line number6 index5 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">switch</code><code class="cpp plain">(msg)</code></div><div class="line number7 index6 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">{</code></div><div class="line number8 index7 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Allocate a new CustCtrl class for this window.</code></div><div class="line number9 index8 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">case</code> <code class="cpp plain">WM_NCCREATE:</code></div><div class="line number10 index9 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">ccp = </code><code class="cpp keyword bold">new</code> <code class="cpp plain">CustCtrl(hwnd);</code></div><div class="line number11 index10 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">SetCustCtrl(ccp);</code></div><div class="line number12 index11 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">(ccp != NULL);</code></div><div class="line number13 index12 alt2">&nbsp;</div><div class="line number14 index13 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Clean up when the window is destroyed.</code></div><div class="line number15 index14 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">case</code> <code class="cpp plain">WM_NCDESTROY:</code></div><div class="line number16 index15 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">delete</code> <code class="cpp plain">ccp;</code></div><div class="line number17 index16 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">break</code><code class="cpp plain">;</code></div><div class="line number18 index17 alt1">&nbsp;</div><div class="line number19 index18 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Handle messages</code></div><div class="line number20 index19 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">case</code> <code class="cpp plain">WM_PAINT:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code><code class="cpp keyword bold">return</code> <code class="cpp plain">ccp-&gt;OnPaint(wParam, lParam);</code></div><div class="line number21 index20 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">case</code> <code class="cpp plain">WM_ERASEBKGND:&nbsp;&nbsp;&nbsp; </code><code class="cpp keyword bold">return</code> <code class="cpp plain">1;</code></div><div class="line number22 index21 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">case</code> <code class="cpp plain">WM_LBUTTONDOWN:&nbsp;&nbsp; </code><code class="cpp keyword bold">return</code> <code class="cpp plain">ccp-&gt;OnLButtonDown(wParam, lParam);</code></div><div class="line number23 index22 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">case</code> <code class="cpp plain">WM_SETFONT:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code><code class="cpp keyword bold">return</code> <code class="cpp plain">ccp-&gt;OnSetFont(wParam, lParam);</code></div><div class="line number24 index23 alt1">&nbsp;</div><div class="line number25 index24 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">default</code><code class="cpp plain">:</code></div><div class="line number26 index25 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">break</code><code class="cpp plain">;</code></div><div class="line number27 index26 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">}</code></div><div class="line number28 index27 alt1">&nbsp;</div><div class="line number29 index28 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">DefWindowProc(hwnd, msg, wParam, lParam);</code></div><div class="line number30 index29 alt1"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div><p>Notice
 the difference in the way the C++ class is allocated. The class's 
constructor can be used to initialize the object. Also, look at the way 
the message handler functions are called through a pointer to the class.
 There is no need to pass the pointer as the first parameter, because a 
C++ member function has access to the object's class members. This 
means, in our message handler functions, there is no need to constantly 
write ptr-&gt;<i>attribute</i>, because C++ does this automatically for you with the implicit <b>this</b> pointer. Look at this small example:</p>
<div><div id="highlighter_648637" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">LRESULT</code> <code class="cpp plain">CustCtrl::OnSetFont(</code><code class="cpp color1 bold">WPARAM</code> <code class="cpp plain">wParam, </code><code class="cpp color1 bold">LPARAM</code> <code class="cpp plain">lParam)</code></div><div class="line number2 index1 alt1"><code class="cpp plain">{</code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">// Change the font</code></div><div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">hFont = (</code><code class="cpp color1 bold">HFONT</code><code class="cpp plain">)wParam; </code></div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">0;</code></div><div class="line number6 index5 alt1"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div><p>This
 is the advantage of using C++. It makes writing this type of 
object-oriented program alot easier. Now, just one last thing, which is 
very important. In the C++ class, I defined the window procedure to be a
 <b>static function</b>. I will explain why this important detail is necessary.</p>
<p>A standard C++ member function always has an implicit first argument, the <b>*this</b>
 pointer. Whenever you call a member function, the C++ compiler 
automatically includes this hidden argument. This means that our window 
procedure, if it had been a normal class member, would really have 
looked like this:</p>
<div><div id="highlighter_902206" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">LRESULT</code> <code class="cpp plain">CALLBACK CustCtrl::WndProc( CustCtrl *</code><code class="cpp keyword bold">this</code><code class="cpp plain">, </code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwnd, ...);</code></div></div></td></tr></tbody></table></div></div><p>You
 never declare a member function like this, but this is how it works 
"behind the scenes". Now, you are probably aware that this function 
prototype is incompatible with the standard window procedure prototype. 
In fact, it is impossible to use a member function as a window 
procedure. Therefore, we need to define the window procedure as a <b>static member</b>, so that the <b>*this</b> pointer is omitted from the function prototype.</p>
<div><div id="highlighter_669439" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">LRESULT</code> <code class="cpp plain">CALLBACK CustCtrl::WndProc(</code><code class="cpp color1 bold">HWND</code> <code class="cpp plain">hwnd, ...);</code></div></div></td></tr></tbody></table></div></div><p>Obviously
 this means that the window procedure cannot access any member 
variables. This is why we have to obtain a pointer to the correct class 
for each window, and call the member functions through that pointer. 
This is a small inconvenience though for the design benefits that C++ 
gives us.</p>
<p><b>Important:</b> Although a custom control can be written using C++,
 this is as far as it goes. The "interface" to the control (i.e. how it 
is created, how to move it / size it) hasn't changed at all. This makes 
it possible to use C++ to create a custom control, and then use it in a C
 project. This way you get the best of both worlds.</p>
<h2>
	Conclusion</h2>
<p>We have covered alot of ground in this tutorial, but it was necessary
 because custom controls, whilst not difficult, require careful coding 
and a reasonable understanding of Windows programming.</p>
<p>Although the example control presented in this tutorial was very 
simple, the concepts are exactly the same as for a more complicated 
control. I have shown you the techniques required to build a custom 
control from scratch. It is now up to you to take these techniques and 
apply them to your own projects.</p>
<p>Well, happy coding,</p>
<p>James.</p>
</div></div></div>  	</div>
  	
      	
    	    <div class="links"></div>
	          
	</div> <!-- /node-inner -->
</div> <!-- /node-->

  </div>
</div>
  </div>
        </div>

        
      </div>
    </div> <!-- /content-inner /content -->

   

        <div id="sidebar-first" class="maincolumn sidebar first">
        <div id="sidebar-first-inner" class="inner">
            <div class="region region-sidebar-first">
    <div id="block-nodeinfo-nodeinfo" class="block block-nodeinfo block-first block-last">

    
  <div class="content">
    <h2>20 Nov 2001</h2><p class="breadcrumb">Posted in <b><a href="http://www.catch22.net/tuts">Tutorials</a></b></p><div class="field field-name-field-tags field-type-taxonomy-term-reference field-label-hidden"><div class="field-items"><div class="field-item even"><a href="http://www.catch22.net/taxonomy/term/3" typeof="skos:Concept" property="rdfs:label skos:prefLabel">win32</a></div></div></div>  </div>
</div>
  </div>
        </div>
      </div>
     <!-- /sidebar-first -->

    

  </div> <!-- /main -->

  <!-- ______________________ FOOTER _______________________ -->

      <div id="footer">
        <div class="region region-footer">
    <div id="block-system-powered-by" class="block block-system block-first block-last">

    
  <div class="content">
    <span>Powered by <a href="http://drupal.org/">Drupal</a></span>  </div>
</div>
  </div>
    </div> <!-- /footer -->
  
</div> <!-- /page -->
  <script type="text/javascript" src="Custom%20Controls%20_%20Catch22_files/js_Rk5YIkK6m2gKTGH-GrMu0pM_PlMKXnI0ktQUgXw1XgA.js"></script>


<div id="lightbox2-overlay" style="display: none;"></div>      <div id="lightbox" style="display: none;" class="lightbox2-orig-layout">        <div style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);" id="outerImageContainer"><div id="modalContainer" style="display: none; padding: 10px;"></div><div id="frameContainer" style="display: none; padding: 10px;"></div><div id="imageContainer" style="display: none; padding: 10px;"><img id="lightboxImage" alt=""><div id="hoverNav"><a style="padding-top: 10px;" id="prevLink" title="Previous" href="#"></a><a style="padding-top: 10px;" id="nextLink" title="Next" href="#"></a></div></div><div id="loading"><a href="#" id="loadingLink"></a></div></div>        <div style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);" id="imageDataContainer" class="clearfix">          <div id="imageData"><div id="imageDetails"><span id="caption"></span><span id="numberDisplay"></span></div><div id="bottomNav"><div id="frameHoverNav"><a style="padding-top: 10px;" id="framePrevLink" title="Previous" href="#"></a><a style="padding-top: 10px;" id="frameNextLink" title="Next" href="#"></a></div><a style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);" id="bottomNavClose" title="Close" href="#"></a><a id="bottomNavZoom" href="#"></a><a id="bottomNavZoomOut" href="#"></a><a id="lightshowPause" title="Pause Slideshow" href="#" style="display: none;"></a><a id="lightshowPlay" title="Play Slideshow" href="#" style="display: none;"></a></div></div>        </div>      </div><div align="right" style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: rgb(0, 0, 0); position: absolute; border: 2px solid rgb(136, 136, 136); z-index: 99; direction: ltr; width: 20px; height: 0px; left: 915px; top: 5555px; visibility: hidden;" id="translationDiv"></div></body></html>